-
Notifications
You must be signed in to change notification settings - Fork 170
[examples/revm] Add REVM example on threshold-simplex #2495
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[examples/revm] Add REVM example on threshold-simplex #2495
Conversation
|
Haven't read into this deeply just yet, but awesome to see someone doing this on a lower-level than communicating with ETH ELs over the engine API :) Would be really neat to add a |
This would be :100000000000: |
3c3680e to
20ed6d2
Compare
Thanks for the quick feedback. I really appreciate the suggestion. Agree that a QMDB-backed backend would be a great “Commonware-native” next step. One caveat I’ve been thinking about: revm::Database is a synchronous, hot-path interface, while commonware_storage::qmdb is async (and REVM’s built-in async→sync adapter is Tokio-based). I don’t want to accidentally introduce blocking in the EVM execution loop or pull Tokio in outside runtime. A direction that seems workable is a layered backend: keep a CacheDB/InMemoryDB overlay for sync reads during execution, and add explicit async load_from_qmdb / flush_to_qmdb at finalized block boundaries (so QMDB provides persistence, but the EVM still reads from an in-memory cache). Does that match what you had in mind, or is there a better pattern you’d prefer for bridging the async/sync boundary here? |
|
I'm sorry for the big PR. I know it's not ideal and hard to review. I split it into many small commits to make it more manageable. Please let me know if I should break it into smaller PRs. |
Add a minimal execution layer (EthEvmBuilder + transact_raw) that converts REVM EvmState diffs into deterministic StateChanges, updates the rolling StateRoot, and commits via DatabaseCommit. Includes a single ETH transfer unit test using InMemoryDB.
Introduce a minimal application/mailbox that implements consensus::simplex Automaton/Relay/Reporter over opaque Sha256 digests, builds placeholder blocks, and reuses the alloy-evm execution path when data is present. Also add a shared EVM env helper (chain_id + block env fields).
Teach the simplex mailbox to broadcast full encoded blocks out-of-band via a p2p Sender when a proposal digest is accepted. The application now ingests received block bytes, queues verify requests until the block arrives, and verifies proposals by re-executing against the parent state and checking state_root.
Wire the simulated network to run N threshold-simplex nodes with out-of-band block broadcast and re-execution verification. Add a deterministic smoke test that finalizes a few blocks and checks all nodes converge on the same head, state_root, and transfer balances.
Persist a 32-byte seed hash per finalized/notarized digest, use it as the next block's prevrandao, and assert seed convergence in the deterministic sim.
Install a stateful precompile at 0x…00ff that returns block.prevrandao, and add unit tests for direct calls and contract-based access.
README now documents the prevrandao/seed flow and the seed precompile address; the CLI prints the finalized head, state root, seed and balances.
Refactor the EVM execution tests with explicit prepare/execute/assert structure and small helpers for funding and nonce retrieval.
Split the large event loop into a small dispatcher and concept-level handlers (genesis/propose/verify/broadcast/report + control queries), keeping behavior unchanged.
Extract helpers for channel registration, application startup, block forwarding, and simplex engine config to make node bootstrap easier to read.
Rename the stream-select enum from Event::{Ingress,Control} to Input::{Consensus,Control} to better reflect the source of messages.
Rename consensus mailbox messages to ConsensusRequest and application handle messages to ApplicationRequest, and update the application actor wiring for clearer concepts.
Of course, it's better indeed. |
All our examples use the tokio-runtime (our deterministic runtime is really just for testing). Can we do async load at the boundaries and have it still work? Seems like you won't know the keys it will touch a priori? |
I believe you mean testing the lib and the examples aren't included? I initially used the deterministic runtime to test this example, but I will use a different approach then.
You're right. I'll work on a proposal using Tokio. Thanks a lot for the feedback! |
|
Hey @patrick-ogrady, quick question: is it expected to use the tokio runtime with When I run the sim in the example, I’m getting bind errors from the simulated network: It looks like the simulated network picks a pseudo‑random IP and then actually binds sockets under tokio, which fails on macOS in my environment. Under deterministic runtime this doesn’t happen (since it’s a virtual network). Is tokio + simulated P2P a supported/expected combo? If not, what’s the preferred pattern for examples that need tokio but still want a simulated network? |
|
@patrick-ogrady Quick summary of what has been done:
Question: should we switch to an authenticated QMDB variant (e.g. |
|
Using QMDBs root for the state commitment would be HUGE (can use it for state sync/proofs externally). At that point, I'm a very happy camper. |
Given the goal of external state sync/proofs, I propose switching the example to an authenticated QMDB using the ordered current variant (so we can provide inclusion + exclusion proofs and complete range proofs). Plan:
If you’re good with ordered + a combined root, I’ll move forward. |
I think that would be the most powerful example, although I've always believed you could get away with In any case, I think it'll be easy to swap out the QMDB as needed (for different variants). |
The benefit to using a simpler one at first is that we already have state sync done. |
Closes #431
Adds a new example crate commonware-revm (examples/revm) demonstrating how to wire threshold-simplex consensus into block execution with an EVM.
Run:
cargo run -p commonware-revm-chain --release -- --nodes 4 --blocks 5 --seed 1Test:
cargo test -p commonware-revm